$(function () {

    var Employee = function (e) {
        var self = this;
        self.Name = ko.observable(e ? e.Name : '').extend({ required: true });
        self.Id = ko.observable(e ? e.Id : '');
        self.Manager = ko.observable(e ? e.Manager : '');
        self.Title = ko.observable(e ? e.Title : '');
        self.Salary = ko.observable(e ? e.Salary : '').extend({ required: true, min: 1000, max: 1000000 });
        self.Age = ko.observable(e ? e.Age : '').extend({ required: true, min: 18, max: 80 });
        self.ManagerId = ko.observable(e ? e.ManagerId : '');
        self.errors = ko.validation.group(self);
        self.isValid = function () {
            if (self.errors().length > 0) {
                self.errors.showAllMessages();
                return false;
            }
            return true;
        };
    };
    var EmployeesViewModel = function () {
        var self = this;
        var url = "/api/employees";
        var refresh = function () {
            waitingDialog({});
            $.getJSON(url, {}, function (data) { self.Employees(data); closeWaitingDialog(); });
        };

        // Public data properties
        self.Employees = ko.observableArray([]);
        self.newEmployee = ko.observable(new Employee());
        self.filter = ko.observable();
        self.filterEmployees = ko.dependentObservable(function () {
            var filter = this.filter();

            if (!filter) {
                return this.Employees();
            } else {
                return ko.utils.arrayFilter(this.Employees(), function (item) {
                    if (item.ManagerId && item.ManagerId == filter) {
                        return true;
                    }
                    return false;
                });
            }
        }, self);


        // Public operations
        self.saveEmployee = function () {
            if (!self.newEmployee().isValid()) {
                return;
            }
            var item = ko.utils.unwrapObservable(self.newEmployee());
            waitingDialog({});
            $.ajax({
                type: (item.Id > 0 ? 'PUT' : 'POST'),
                url: url + (item.Id > 0 ? '?id=' + item.Id : ''),
                data: ko.toJS(item),
                success: function (data) {
                    if (item.Id() <= 0)
                        self.Employees.push(data);
                    else {
                        for (i = 0; i < self.Employees().length; i++) {
                            var emp = self.Employees()[i];
                            if (emp.Id == item.Id()) {
                                self.Employees.replace(self.Employees()[i], data);
                            }
                            if (emp.ManagerId == item.Id()) {
                                var managedEmployee = new clone(emp);
                                managedEmployee.Manager = data;
                                self.Employees.replace(self.Employees()[i], managedEmployee);
                            }
                        }
                    }
                    $(".ui-icon-closethick").trigger('click');
                },
                error: function (err) {
                    var err = JSON.parse(err.responseText);
                    var errors = "";
                    for (var key in err) {
                        if (err.hasOwnProperty(key)) {
                            errors += key.replace("employee.", "") + " : " + err[key];
                        }
                    }

                    $("<div></div>").html(errors).dialog({ modal: true, title: JSON.parse(err.responseText).Message, buttons: { "Ok": function () { $(this).dialog("close"); } } }).show();
                },
                complete: function () {
                    closeWaitingDialog();
                }
            });
            //self.reset();

        };
        self.reset = function () { self.newEmployee(new Employee()); };
        self.createEmployee = function () {
            self.newEmployee(new Employee());
            $('#employeeEditor').dialog({ width: 450, modal: true, close: function () { self.reset(); } });
        };
        self.editEmployee = function (employee) {
            self.newEmployee(new Employee(employee));
            $('#employeeEditor').dialog({ width: 450, modal: true, close: function () { self.reset(); } });
        };
        self.cancelOperation = function () {
            $(".ui-icon-closethick").trigger('click');
            //self.reset();
        };
        self.removeEmployee = function (employee) {
            if (confirm("Are you sure you want to delete this employee?")) {
                var id = employee.Id;
                waitingDialog({});
                $.ajax({
                    type: 'DELETE', url: url + '/' + id,
                    success: function () { self.Employees.remove(employee); },
                    error: function (err) {
                        var error = JSON.parse(err.responseText);
                        $("<div></div>").html(error.Message).dialog({ modal: true, title: "Error", buttons: { "Ok": function () { $(this).dialog("close"); } } }).show();
                    },
                    complete: function () { closeWaitingDialog(); }
                });
            }
        };
        refresh();
    };
    ko.applyBindings(new EmployeesViewModel());
});

var clone = (function () {
    return function (obj) { Clone.prototype = obj; return new Clone() };
    function Clone() { }
}());